/*
 * @(#)EmailMessageSenderComparator.java
 *
 * Copyright (c) 2004 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */

package com.dcivision.upgrade;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.upgrade.handler.UpgradeHandler;

/**
 * Standard implement of <code>UpgradeContext</code>.
 * Provides a storage to store special context by key-value pairs.
 * 
 * @author      Brook.Huang
 * @company     DCIVision Limited
 * @creation    19/04/2007
 * @version     $Revision: 1.8 $
 */
public class StandardUpgradeContext implements UpgradeContext, UpgradeState {

  private static final Log logger = LogFactory.getLog(StandardUpgradeContext.class);
  
  private Connection conn = null;

  private boolean isParticularReportToClient = true;

  private UpgradeRequest upgradeRequest = null;

  private boolean isUpgradeCompleted = false;

  private boolean isExceptionOccur = false;

  private UpgradeHandler topUpgradeHandler = null;

  private Throwable exception = null;

  private StringBuffer report = new StringBuffer();

  private Map cutomizeContextMap = new HashMap();

  public StandardUpgradeContext(Connection conn, UpgradeRequest upgradeRequest, boolean isParticularReportToClient, Map customizeContext)
      throws Exception {
    if (conn == null || upgradeRequest == null) {
      throw new IllegalArgumentException("Error occurs when initialize upgrade context, DB conn or upgradeRequest cannt be null!");
    }

    this.conn = conn;
    this.upgradeRequest = upgradeRequest;
    this.isParticularReportToClient = isParticularReportToClient;

    if (customizeContext != null) {
      this.cutomizeContextMap.putAll(customizeContext);
    }
  }

  public StandardUpgradeContext(Connection conn, UpgradeRequest upgradeRequest, boolean isParticularReportToClient) throws Exception {
    this(conn, upgradeRequest, isParticularReportToClient, null);
  }

  public Connection getUpgradeConnection() {
    return conn;
  }

  public UpgradeRequest getUpgradeRequest() {
    return upgradeRequest;
  }

  public boolean isParticularReportToClient() {
    return isParticularReportToClient;
  }

  public boolean isUpgradeCompleted() {
    return isUpgradeCompleted;
  }

  public void setUpgradeCompleted(boolean isUpgradeCompleted) {
    this.isUpgradeCompleted = isUpgradeCompleted;
  }

  public boolean isExceptionOccur() {
    return isExceptionOccur;
  }

  public void setExceptionOccur(boolean isExceptionOccur) {
    this.isExceptionOccur = isExceptionOccur;
  }

  public void setTopUpgradeHandler(UpgradeHandler topUpgradeHandler) {
    this.topUpgradeHandler = topUpgradeHandler;
  }

  public UpgradeHandler getTopUpgradeHandler() {
    return topUpgradeHandler;
  }

  public Throwable getException() {
    return exception;
  }

  public void setException(Throwable exception) {
    this.exception = exception;
  }

  public void logReport(CharSequence title, CharSequence detail) {

    synchronized (report) {
      if (title != null) {
        report.append(title);
      }
      if (detail != null) {
        printParticularReport(detail);
      }
    }

  }

  public String getReport() {
    return (report.toString());
  }

  private void printParticularReport(CharSequence message) {
    if (isParticularReportToClient) {
      report.append(message);
    }
  }

  /**
   * Return the upgrade report and reset the report for next progress.
   */
  public String getProgressReport() {
    String originalReport = null;

    synchronized (report) {
      originalReport = report.toString();
      report = new StringBuffer();
    }

    return originalReport;
  }

  public UpgradeState getUpgradeState() {
    return (this);
  }

  public Object getAttribute(String key) {
    return (cutomizeContextMap.get(key));
  }

  public void setAttribute(String key, Object value) {
    cutomizeContextMap.put(key, value);
  }

  public void commit() {
    try {
      conn.commit();
      logReport("<p><b>UPGRADE SUCCESS</b></p>\n", null);
    } catch (SQLException exp) {
      logger.error("Exception caught while commiting.", exp);
      logReport("<font color=red>DB COMMIT FAILD!</font></P>\n", null);
    }
    
  }

  /**
   * Release resources associated to this context.
   */
  public void release() {
    DbUtils.closeQuietly(conn);
  }
  
  

}
